﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EssentialWebFramework.Utilities.Redis
{
    /// <summary>
    /// 利用 Redis 生成 Id 的工厂类
    /// </summary>
    public class RedisIdFactory
    {
        /// <summary>
        /// 时间部分长度
        /// </summary>
        private const byte TIMESTAMP_LENGTH = 31;

        /// <summary>
        /// 随机值长度
        /// </summary>
        private const byte RANDOM_LENGTH = 32;

        /// <summary>
        /// 缓存 TAG
        /// </summary>
        private const string CACHE_INC_TAG = "INC";

        /// <summary>
        /// 开始的时间戳（从 2024-01-01 开始）
        /// </summary>
        private static long BEGIN_TIMESTAMP = DateTimeOffset.Parse("2024-01-01").ToUniversalTime().ToUnixTimeSeconds();

        /// <summary>
        /// 获取新的 Id
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static long NextId(string key)
        {
            // 1. 生成时间戳
            long timestamp = DateTimeOffset.Now.ToUniversalTime().ToUnixTimeSeconds() - BEGIN_TIMESTAMP;

            // 2. 利用 Redis 的 INC 命令，生成 序列号
            var redisDB = RedisClientService.RedisDB;
            string dateStr = DateTime.Now.ToString("yyyyMMdd");

            // KEY  = 入参 key + TAG + 时间（按天）的字符串组成
            long serialNumber = redisDB.StringIncrement($"{key}:{CACHE_INC_TAG}:{dateStr}");

            // 时间戳左移 32 位，和 序列号做 或运算
            return timestamp << 32 | serialNumber;
        }
    }
}
